

#include "stdlib.h"


#include "../../1_Application/Include/APP_WorkingNormalState.h"

#include "../../2_Process/Include/Cmp_LQC_Process.h"
#include "../../2_Process/Include/Cmp_Onboarding.h"

#include "../../3_Component/Include/Cmp_KeyScan.h"
#include "../../3_Component/Include/Cmp_SetError.h"



#include "../../4_Library/Include/general.h"
#include "../../4_Library/Include/Int.h"
#include "../../4_Library/Include/Lib_UartComm.h"
#define __COMMSUBMICOM__
#include "../../4_Library/Include/Lib_CommSubMicom.h"
#undef __COMMSUBMICOM__
#include "../../4_Library/Include/Lib_SensingADC.h"
#include "../../4_Library/Include/Lib_EEPROM.h"


#include "../../5_WROS/Include/DDI_BootingDriver.h"
#include "../../5_WROS/Include/DDI_RegisterDriver.h"


#include "../../6_Vablesource/Include/Vable_ModelInformation.h"

extern const T_BufferDef mpstBufferInfo[CommStateMax][PlatformMax];
extern const UINT8 gaucBeeperInfo[PlatformMax][BeeperInformMax];
extern const UINT8 gauCommInfo[PlatformMax][CommInformMax];

typedef void(*const T_TYPE_FUNC_P)(UINT8*);

UINT8 ucRetKeyVal = 0;
UINT8 ucKeydisable = 0;
UINT8 mucReceiveSTX = 0;
UINT8 mucKeyValue = 0;
UINT8 mucKeyCount = 0;
UINT8 mucDoorState = 0;
UINT8 mucWifiState = 0;
UINT8 mucResultFlash = 0;
UINT8 mucProduceInfo = 0;
UINT16 mucRecvDispCUM = 0;
UINT8 mucRecvPackCNT = 0;
UINT8 mucSendPackCNT = 0;
UINT8 ShiftTopgunAmrStep = 0;

UINT16 punOption[_OptionInfo_MAX] = {0,};

T_Time PstSendGapTime;

static UINT8 KeyCountBefore = 0;
static UINT8 PCRecvPackCNTBefore = 0;
static UINT8 ucPC2JIG_ACK = 0;


void SET_STX(UINT8 ucSTX)
{
	STX = ucSTX;
}

UINT8 GET_STX()
{
	return STX;
}

#define DisPacket
void Comm_DispSetPacket_Normal(UINT8* pucSendBuffer, UINT8 ucCommOper)
{
    /*
	if(Get_JigPlatform() == Vivace
		|| Get_JigPlatform() == Topgun_WW
		|| Get_JigPlatform() == New_Topgun)
	{
		if(API_SIO_RecvDataRead(SC0) != 0)
		{
			STX = mpstBufferInfo[ucCommOper][Get_JigPlatform()].ucStx;
		}
		else
		{;}
	}
	else
	{
		STX = mpstBufferInfo[ucCommOper][Get_JigPlatform()].ucStx;
	}
*/

	switch(Get_JigPlatform())
	{
		case Vivace:
			pucSendBuffer[0] = STX;
			pucSendBuffer[1] = gauCommInfo[Get_JigPlatform()][SEND_DATA_SIZE];
			pucSendBuffer[12] = 0x06;
			pucSendBuffer[13] = (Sys_GetMainStatus() * 130);
			pucSendBuffer[14] = ERROR_State;
			pucSendBuffer[15] = Sys_GetMainStatus();
			pucSendBuffer[17] = Sys_GetBeepStatus();
			pucSendBuffer[26] = Comm_EncodeTestModeStep();
			pucSendBuffer[29] = (0x01 << 6);
			break;

		case Topgun_WW:
			pucSendBuffer[0] = STX;
			pucSendBuffer[1] = gauCommInfo[Get_JigPlatform()][SEND_DATA_SIZE];
			pucSendBuffer[3] = (Sys_GetMainStatus() == 0 ? COMM_MODE_NORMAL : COMM_MODE_LQC_TEST);
			pucSendBuffer[5] = ERROR_State;
			pucSendBuffer[11] = Sys_GetBeepStatus();
			pucSendBuffer[29] = Sys_GetMainStatus();
			pucSendBuffer[39] = 0x01;
			pucSendBuffer[40] = Comm_EncodeTestModeStep();
			break;

		case Mini:
			pucSendBuffer[0] = STX;
			pucSendBuffer[1] = gauCommInfo[Get_JigPlatform()][SEND_DATA_SIZE];
			pucSendBuffer[5] = Sys_GetMainStatus();
			pucSendBuffer[29] = Comm_EncodeTestModeStep();
			pucSendBuffer[30] = Sys_GetBeepStatus();
			break;

		case Mega_Titan:
			pucSendBuffer[0] = gauCommInfo[Get_JigPlatform()][SEND_DATA_SIZE];
			pucSendBuffer[1] = STX;

			pucSendBuffer[2] = 0x06;
			pucSendBuffer[3] = (UINT8)(Sys_GetMainStatus() * 0x40 | ERROR_State);
			pucSendBuffer[4] = Sys_GetMainStatus();
			pucSendBuffer[7] = Sys_GetBeepStatus();
			pucSendBuffer[16] = Comm_EncodeTestModeStep();
			break;

		case LCD_NT_VX:
			pucSendBuffer[0] = STX;
			pucSendBuffer[1] = gauCommInfo[Get_JigPlatform()][SEND_DATA_SIZE];
			pucSendBuffer[5] = ERROR_State;
			pucSendBuffer[10] = (4 << 4);
			break;

		default:
			break;
	}
}

void Comm_DispRecvPacket_Normal(UINT8* pucRecvBuffer)
{
	switch(Get_JigPlatform())
	{
		case Vivace:
			mucReceiveSTX = pucRecvBuffer[0];
			mucKeyValue = pucRecvBuffer[3];
			mucKeyCount = pucRecvBuffer[4];
			mucDoorState = pucRecvBuffer[14];
			mucWifiState = pucRecvBuffer[15];

			punOption[_Real_Option] = ((UINT16)pucRecvBuffer[8] << 8\
												| pucRecvBuffer[9]);
			Comm_SetKeyValue_1(mucKeyValue, mucKeyCount);
			break;

		case Topgun_WW:
			mucReceiveSTX = pucRecvBuffer[0];
			mucKeyValue = pucRecvBuffer[2];
			mucKeyCount = pucRecvBuffer[3];
			mucDoorState = ((pucRecvBuffer[5] >> 1) & 0x03);

			Comm_SetKeyValue_3(mucKeyValue, mucKeyCount);
			break;

		case Mini:
			mucReceiveSTX = pucRecvBuffer[0];
			mucKeyValue = pucRecvBuffer[2];
			mucKeyCount = pucRecvBuffer[3];

			Comm_SetKeyValue_2(mucKeyValue, mucKeyCount);
			break;

		case Mega_Titan:
			mucReceiveSTX = pucRecvBuffer[0];
			mucKeyValue = pucRecvBuffer[3];
			mucKeyCount = pucRecvBuffer[4];

			Comm_SetKeyValue_1(mucKeyValue, mucKeyCount);
			break;

		case LCD_NT_VX:
			mucReceiveSTX = pucRecvBuffer[0];
			mucKeyValue = pucRecvBuffer[3];
			mucKeyCount = pucRecvBuffer[4];

			Comm_SetKeyValue_1(mucKeyValue, mucKeyCount);
			break;

		default:
			break;
	}
}

#define OPPacket
void Comm_OptionSetPacket_Normal(UINT8* pucSendBuffer, UINT8 ucCommOper)
{
	pucSendBuffer[0] = mpstBufferInfo[ucCommOper][Get_JigPlatform()].ucStx;
	pucSendBuffer[1] = gauCommInfo[Get_JigPlatform()][SEND_DATA_SIZE];
	pucSendBuffer[3] = 'F';
	pucSendBuffer[4] = 'C';
	pucSendBuffer[5] = 'T';
	pucSendBuffer[6] = gunOpWriteFlag;
	pucSendBuffer[7] = (UINT8)(punOption[_FCT_Send_OP] >> 8);
	pucSendBuffer[8] = (UINT8)(punOption[_FCT_Send_OP] & 0xFF);
	pucSendBuffer[20] = 0x06;

}

void Comm_OptionRecvPacket_Normal(UINT8* pucRecvBuffer)
{
	mucReceiveSTX = pucRecvBuffer[0];
	mucResultFlash = pucRecvBuffer[6];
	punOption[_FCT_Recv_OP] = ((UINT16)pucRecvBuffer[7] << 8\
												| pucRecvBuffer[8]);

	mucRecvDispCUM = ((UINT16)pucRecvBuffer[13] << 8\
												| pucRecvBuffer[14]);

}

#define PCPacket
void Comm_PCSetPacket_Normal(UINT8* pucSendBuffer, UINT8 ucCommOper)
{
	pucSendBuffer[0] = mpstBufferInfo[ucCommOper][Get_JigPlatform()].ucStx;
	pucSendBuffer[1] = gauCommInfo[Get_JigPlatform()][SEND_DATA_SIZE];
	pucSendBuffer[2] = CounterAddLimite(mucSendPackCNT, 0, 255);
	pucSendBuffer[3] = 'F';
	pucSendBuffer[4] = 'C';
	pucSendBuffer[5] = 'T';

	pucSendBuffer[6] = mucProduceInfo;
	pucSendBuffer[7] = (mucProduceInfo == 0x01 ? 0x00 : ++mucProduceInfo);

	pucSendBuffer[8] = (punOption[_Real_Option] == punOption[_PC_Recv_OP] ? 0x01 : 0x00);
	//pucSendBuffer[9] = (DOOR_SEN_SIGNAL == SET ? SET : CLR);

	pucSendBuffer[20] = (ucPC2JIG_ACK == SET ? 0x06 : 0x15);
	(pucSendBuffer[20] == 0x06 ? ucPC2JIG_ACK = CLR : CLR);

	pucSendBuffer[21] = (UINT8)(punOption[_Real_Option] >> 8);
	pucSendBuffer[22] = (UINT8)(punOption[_Real_Option] & 0xFF);

	pucSendBuffer[45] = (UINT8)(mucRecvDispCUM >> 8);
	pucSendBuffer[46] = (UINT8)(mucRecvDispCUM & 0xFF);
	pucSendBuffer[47] = mpstBufferInfo[ucCommOper][Get_JigPlatform()].ucEtx;

}

void Comm_PCRecvPacket_Normal(UINT8* pucRecvBuffer)
{
	mucReceiveSTX = pucRecvBuffer[0];
	mucRecvPackCNT = pucRecvBuffer[2];
	mucProduceInfo = pucRecvBuffer[6];
	punOption[_PC_Recv_OP] = ((UINT16)pucRecvBuffer[8] << 8 | pucRecvBuffer[9]);
	Comm_SetPCOption(mucRecvPackCNT);
}
UINT16 Uart_CRCMaker(UINT8* pucBuffer, UINT8 ucLength)
{	UINT8 uci = 0;
	UINT16 unCrc = 0;
	UINT16 unTemp = 0;
	UINT16 unQuick = 0;

	for(uci = 0; uci < ucLength; uci++)
	{	unTemp = (unCrc >> 8) ^ *pucBuffer++;
		unCrc <<= 8;
		unQuick = unTemp ^ (unTemp >> 4);
		unCrc ^= unQuick;
		unQuick <<= 5;
		unCrc ^= unQuick;
		unQuick <<= 7;
		unCrc ^= unQuick;
	}
	return (unCrc);
}

void Uart_CrcPacketEncode(UINT8* pucPacket, UINT8 ucEtx)
{
	UINT16 unCrcValue = 0;
        UINT8 Index = (Get_JigPlatform() == Mega_Titan ? 0 : 1);
	unCrcValue = Uart_CRCMaker(pucPacket, (UINT8)(pucPacket[Index] - 3));
	pucPacket[pucPacket[Index] - 3] = (UINT8)((unCrcValue & 0xFF00) >> 8);
	pucPacket[pucPacket[Index] - 2] = (UINT8)(unCrcValue & 0x00FF);
	pucPacket[pucPacket[Index] - 1] = ucEtx;

}


void Comm_SetKeyValue_1(UINT8 ucKeyValue, UINT8 ucKeyCount)
{
	if(ucKeydisable == CLR)
	{
		ucKeydisable = SET;

		if(ucKeyCount != KeyCountBefore)
		{
			KeyCountBefore = ucKeyCount;
			ucRetKeyVal = ucKeyValue;
		}
		else
		{;}
	}
	else
	{;}
}


void Comm_SetKeyValue_2(UINT8 ucKeyValue, UINT8 ucKeyCount)
{
	if(ucKeydisable == CLR)
	{

		if((ucKeyValue == POWER_KEY || ucKeyValue == START_PAUSE_KEY) && ucKeyCount != KeyCountBefore)
		{
			ucKeydisable = SET;
			KeyCountBefore = ucKeyCount;
			ucRetKeyVal = ucKeyValue;
		}
		else
		{
			ucRetKeyVal = NO_KEY;
		}
	}
	else
	{;}

}



void Comm_SetKeyValue_3(UINT8 ucKeyValue, UINT8 ucKeyCount)
{
	if(ucKeyCount == 0)
	{
		KeyCountBefore = CLR;
	}
	else if(ucKeyCount != 0 && KeyCountBefore == 0)
	{
		KeyCountBefore = ucKeyCount - 1;
	}
	else if((ucKeyCount - KeyCountBefore) > 1 || KeyCountBefore > ucKeyCount)
	{
		KeyCountBefore = ucKeyCount - 1;
	}
	else
	{;}

	if(ucKeydisable == CLR)
	{

		if((ucKeyCount == KeyCountBefore + 1) && ucKeyValue != NO_KEY)
		{
			ucKeydisable = SET;
			KeyCountBefore++;
			switch(ucKeyValue)
			{
				case 1:
					ucRetKeyVal = POWER_KEY;
					break;

				case 2:
					ucRetKeyVal = START_PAUSE_KEY;
					break;

				default:
					ucRetKeyVal = ucKeyValue;
					break;
			}
		}
		else
		{
			ucRetKeyVal = NO_KEY;
		}
	}
	else
	{;}

}


void Comm_SetPCOption(UINT8 ucRecvPackCNT)
{
	if(ucRecvPackCNT != PCRecvPackCNTBefore)
	{
		PCRecvPackCNTBefore = ucRecvPackCNT;
		ucPC2JIG_ACK = SET;
		gunOpWriteFlag = SET;
	}
	else
	{;}
}

#define Comm_Get
UINT8 Comm_Get_ReceiveSTX()
{
	return mucReceiveSTX;
}

UINT8 Comm_Get_KeyValue()
{
	if(ucRetKeyVal != NO_KEY)
	{
		if(Timer_MsecCheckPassTime(&PstSendGapTime, 100) == SET)
		{
			return ucRetKeyVal;
		}
		else
		{;}
	}
	else
	{
		PstSendGapTime.ulLow = 0;
	}
	return NO_KEY;
}

UINT8 Comm_Get_KeyCount()
{
	return mucKeyCount;
}
void ClearKeyValue(void)
{
	ucRetKeyVal = CLR;
	ucKeydisable = CLR;
}

UINT8 Get_DoorState()
{
	return mucDoorState;
}

UINT8 Get_WifiState()
{
	return mucWifiState;
}

UINT8 Comm_Get_ResultFlash()
{
	return mucResultFlash;
}

void Clear_ResultFlash()
{
	mucResultFlash = CLR;
}

UINT16* Get_OPTION()
{
	return punOption;
}

UINT8 Get_PanelType()
{
	return VVC_PanelType;
}